package com.songlanyun.modules.information.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.enums.IncrementConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;
import com.songlanyun.common.utils.RedisKeys;
import com.songlanyun.common.utils.RedisUtils;
import com.songlanyun.modules.information.dao.InformationDao;
import com.songlanyun.modules.information.entity.InformationEntity;
import com.songlanyun.modules.information.model.dto.InformationDto;
import com.songlanyun.modules.information.model.vo.InformationVo;
import com.songlanyun.modules.information.service.InformationService;
import com.songlanyun.modules.user.entity.SysUserEntity;
import com.songlanyun.modules.user.service.SysUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Service("informationService")
public class InformationServiceImpl extends ServiceImpl<InformationDao, InformationEntity> implements InformationService {

    @Resource
    private RedisUtils redisUtils;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<InformationVo> page = this.baseMapper.queryPage(new Query<InformationVo>().getPage(params), params);
        page.getRecords().forEach(p -> {
            //浏览量
            p.operationSum(
                    IncrementConstant.OperationType.QUERY,
                    IncrementConstant.ScalarType.BROWSE,
                    RedisKeys.IncrementKey.INFORMATION_BROWSE_KEY.getKey(p.getId()));
        });
        return new PageUtils(page);
    }

    @Override
    public InformationEntity getById(Long id, boolean tw) {
        InformationEntity informationEntity = this.baseMapper.selectById(id);
        if (ObjectUtil.isNull(informationEntity) && tw) {
            throw new RRException("资讯不存在");
        }
        return informationEntity;
    }

    @Override
    public InformationVo info(Long id) {
        InformationVo vo = this.getVoById(id);
        vo.loadStick();
        //推荐商品
        vo.loadRecommendGoods();
        //推荐门店
        vo.loadRecommendShops(true);

        return vo;
    }

    @Override
    public InformationVo getVoById(Long id) {
        InformationEntity informationEntity = this.getById(id, true);
        return BeanUtil.toBean(informationEntity, InformationVo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(Long userId, InformationDto dto) {
        InformationEntity informationEntity = BeanUtil.toBean(dto, InformationEntity.class);
        informationEntity.setCreateId(userId);
        informationEntity.setUpdateId(userId);
        informationEntity.setRecommend(false);
        this.baseMapper.insert(informationEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(Long userId, InformationDto dto) {
        InformationEntity informationEntity = this.getById(dto.getId(), true);
        BeanUtil.copyProperties(dto, informationEntity);
        informationEntity.setUpdateId(userId);
        this.baseMapper.updateById(informationEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        this.baseMapper.deleteById(id);
        //删除redis中的缓存
        redisUtils.delete(RedisKeys.IncrementKey.INFORMATION_BROWSE_KEY.getKey(id));
        redisUtils.delete(RedisKeys.IncrementKey.INFORMATION_SHARE_KEY.getKey(id));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void top(InformationDto dto) {
        InformationEntity informationEntity = this.getById(dto.getId(), true);

        Date topEndTime;
        boolean top;
        if (!informationEntity.getTop()
                || informationEntity.getTopEndTime().getTime() <= System.currentTimeMillis()) {
            //置顶
            //必须设置置顶结束时间
            if (ObjectUtils.isNull(dto.getTopEndTime())) {
                throw new RRException("请设置置顶结束时间");
            }
            if (dto.getTopEndTime().getTime() <= System.currentTimeMillis()) {
                throw new RRException("置顶结束时间需要大于当前时间");
            }
            topEndTime = dto.getTopEndTime();
            top = true;
        } else {
            //取消置顶
            topEndTime = null;
            top = false;
        }

        this.lambdaUpdate()
                .eq(InformationEntity::getId, informationEntity.getId())
                .set(InformationEntity::getTopEndTime, topEndTime)
                .set(InformationEntity::getTop, top)
                .update();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void recommend(Long id) {
        InformationEntity information = this.getById(id, true);
        information.setRecommend(!information.getRecommend());
        this.updateById(information);
    }

    @Override
    public PageUtils apiPage(Map<String, Object> params) {
        IPage<InformationVo> page = this.baseMapper.apiPage(new Query<InformationVo>().getPage(params), params);

        //浏览量
        page.getRecords().forEach(l -> {
                    l.operationSum(IncrementConstant.OperationType.QUERY, IncrementConstant.ScalarType.BROWSE, RedisKeys.IncrementKey.INFORMATION_BROWSE_KEY.getKey(l.getId()));
                }
        );
        return new PageUtils(page);
    }

    @Override
    public List<InformationEntity> apiList(Map<String, Object> params) {
        //1：置顶 2：非置顶
        Integer type = MapUtil.getInt(params, "type");
        //查询条数
        Integer limit = MapUtil.getInt(params, "limit");
        Long classifyId = MapUtil.getLong(params, "classify_id");

        List<InformationEntity> list = this.lambdaQuery()
                .and(ObjectUtil.isNotNull(type) && type == 1, b -> b
                        .eq(InformationEntity::getTop, true)
                        .ge(InformationEntity::getTopEndTime, new Date())
                )
                .and(ObjectUtil.isNotNull(type) && type == 2, b -> b
                        .eq(InformationEntity::getTop, false).or()
                        .lt(InformationEntity::getTopEndTime, new Date())
                )
                .eq(ObjectUtil.isNotNull(classifyId), InformationEntity::getClassifyId, classifyId)
                .orderByDesc(InformationEntity::getTopEndTime)
                .orderByDesc(InformationEntity::getCreateTime)
                .last(ObjectUtil.isNotNull(limit), "limit " + limit)
                .list();

        list.forEach(l -> l.operationSum(IncrementConstant.OperationType.QUERY, IncrementConstant.ScalarType.BROWSE, RedisKeys.IncrementKey.INFORMATION_BROWSE_KEY.getKey(l.getId())));
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public InformationVo apiInfo(Long id) {
        InformationVo vo = this.getVoById(id);
        //推荐商品
        vo.loadRecommendGoods();
        //推荐门店
        vo.loadRecommendShops(true);

        //增加浏览量
        vo.operationSum(IncrementConstant.OperationType.ADD, IncrementConstant.ScalarType.BROWSE, RedisKeys.IncrementKey.INFORMATION_BROWSE_KEY.getKey(id));
        return vo;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void share(Long userId, Long id) {
        //查询详情
        InformationVo vo = this.getVoById(id);
        //增加分享量
        vo.operationSum(IncrementConstant.OperationType.ADD, IncrementConstant.ScalarType.SHARE, RedisKeys.IncrementKey.INFORMATION_SHARE_KEY.getKey(id));
    }

    @Override
    public List<InformationEntity> getListTitleAndId() {
        return this.baseMapper.getListTitleAndId();
    }


}
